﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.ComponentModel;
using System.Collections;
using System.Windows.Forms;

namespace FACUI.BasicClass
{
    public class ClassBase
    {
        public object value;

        public ClassBase(object value)
        {
            this.value = value;
        }
    }
    /***************************************************/
    public abstract class Sharp : ICloneable
    {
        private ClassBase _direction;
        private ClassBase _isHideTxt;
        private ClassBase _isSel;
        private ClassBase _lineColor;
        private ClassBase _pointX = new ClassBase(0);
        private ClassBase _pointY = new ClassBase(0);
        private ClassBase _sizeDefineHeight = new ClassBase(0);
        private ClassBase _sizeDefineWidth = new ClassBase(0);
        private ClassBase _subType;
        private ClassBase _text;
        private ClassBase _txtColor;
        private ClassBase _txtFont;
        private ClassBase _txtSize;
        public int changeStep;
        public Pen defaultLinePen;
        public Pen defaultLinePenPrint;
        public List<Digit> digitList;
        public bool isCut;
        public bool isMouseOver;
        public Pen linePen;
        public MapData mapData = null;
        public string paramL;
        public string paramM;
        public string paramR;
        public static Pen perLinePen = new Pen(Color.White, 1f);
        public int quduanAd = -1;
        public Rectangle rectReal;
        public string sharpType;
        public bool showDefaultLinePen;
        public static Color trackColor = Color.GreenYellow;
        public static Pen trackPen = new Pen(Color.Green);
        public static Pen trackRoundPen = new Pen(Color.Red);
        public static Size txtAreaSize = new Size(10, 10);
        public bool 岔后生成了么 = false;

        public static Pen 默认画笔 = new Pen(Color.FromArgb(0x4F, 0x81, 0xBD), 2f) { DashCap= System.Drawing.Drawing2D.DashCap.Round,StartCap=System.Drawing.Drawing2D.LineCap.Round,EndCap=System.Drawing.Drawing2D.LineCap.Round };   
        public string 所属区段名称;
        public static int 显示模式 = 1;
        public bool ShowElement = true;
        public Sharp(MapData mapData, Point point, int direction)
        {
            Color color = new Color();
            this._lineColor = new ClassBase(color);
            this._txtColor = new ClassBase(new Color());
            this._isHideTxt = new ClassBase(false);
            this._isSel = new ClassBase(false);
            this._txtFont = new ClassBase("");
            this._txtSize = new ClassBase(6);
            this._text = new ClassBase("");
            this._subType = new ClassBase("");
            this._direction = new ClassBase(0);
            this.defaultLinePen = new Pen(Color.White, 4f);
            this.defaultLinePenPrint = new Pen(Color.White, 4f);
            this.mapData = mapData;
            this.showDefaultLinePen = true;
            this.point = point;
            this.txtFont = "MS Serif";
            this.txtSize = 6;
            this.direction = direction;
            this.lineColor = Color.FromArgb(0xff, Color.FromArgb(0xffffff));
            this.txtColor = Color.FromArgb(0xff, Color.FromArgb(0xffffff));
            this.linePen = new Pen(this.lineColor, 2f);
            this.sizeDefine = new Size(1, 1);
            this.sharpType = "sb";
            this.text = "";
            this.subType = "";
            this.digitList = new List<Digit>();
            this.isSel = this.isCut = this.isMouseOver = false;
            this.paramL = this.paramM = (string)(this.paramR = null);
        }

        public abstract void addSize(int r);
        public abstract void addSize(int d, Point oldPoint, int oldWidth, int oldHeight, int width, int height);
        public abstract bool changeSubType(string newSubType);
        public abstract void checkLine(int[][][] array4checkLine);
        public object Clone()
        {
            return base.MemberwiseClone();
        }

        public abstract void createDigit(string kglDesc);
        public abstract double distance(Point p, Size r);
        public virtual void draw(Graphics g, MapData ct, Pen usePen)
        {
            usePen.DashCap = System.Drawing.Drawing2D.DashCap.Round;
            usePen.StartCap = System.Drawing.Drawing2D.LineCap.Round;
            usePen.EndCap = System.Drawing.Drawing2D.LineCap.Round;
            this.draw(g, ct.ct, usePen);
        }

        public abstract void draw(Graphics g, MapSet ct, Pen usePen);
        
        public Digit getDigit(string dtype)
        {
            foreach (Digit digit2 in this.digitList)
            {
                if (digit2.code.Equals(dtype))
                {
                    return digit2;
                }
            }
            return null;
        }

        public virtual Point getPoint(char c)
        {
            return new Point(-1, -1);
        }

        public virtual Point getPoint(char c, out int 方向)
        {
            方向 = 0;
            return this.getPoint(c);
        }

        public Point grid2pix(Point o, Size r, Point offset)
        {
            return new Point((o.X * r.Width) + offset.X, (o.Y * r.Height) + offset.Y);
        }

        public abstract bool hasHotPoint(int d);
        public abstract bool hasPoint(Point pt);
        public virtual bool hasPoint(Point pt, out char flag)
        {
            flag = 'N';
            return this.hasPoint(pt);
        }

        public bool inShowArea()
        {
            if (!MapData.需要整体刷新)
            {
                for (int i = 0; i <= this.sizeDefineWidth; i++)
                {
                    for (int j = 0; j <= this.sizeDefineHeight; j++)
                    {
                        if (MapData.showArea.Contains(this.pointX + i, this.pointY + j))
                        {
                            return true;
                        }
                    }
                }
                return false;
            }
            return true;
        }

        public bool isClickedItem(Point p, Size r)
        {
            return (((p.X >= ((this.rectReal.Left * r.Width) / 2)) && (p.Y >= ((this.rectReal.Top * r.Height) / 2))) && ((p.X <= ((this.rectReal.Right * r.Width) / 2)) && (p.Y <= ((this.rectReal.Bottom * r.Height) / 2))));
        }

        public void move(Point to)
        {
            this.pointX += to.X;
            this.pointY += to.Y;
        }

        public abstract void onSpaceChar();
        private Rectangle regHotPoint(Hashtable hot2item, ref Point tt, List<Rectangle> rclist, Cursor cursor, int d)
        {
            Rectangle key = new Rectangle(tt, new Size(2, 2));
            hot2item.Remove(key);
            hot2item.Add(key, new HotPoint(key, d, cursor, this));
            rclist.Add(key);
            return key;
        }

        public abstract void resetSize();
        public bool setDigit(string dtype, Digit ditem)
        {
            foreach (Digit digit in this.digitList)
            {
                if (digit.code.Equals(dtype))
                {
                    digit.name = ditem.name;
                    digit.isLogic = ditem.isLogic;
                    break;
                }
            }
            return ditem.isLogic;
        }

        public static void set显示模式(bool isBasic)
        {
            if (isBasic)
            {
                显示模式 = 1;
            }
            else
            {
                显示模式 = 2; 
            }
        }
   
        public virtual string toStringExtern()
        {
            if ("sbDC".Equals(this.sharpType) || "sbWCQD".Equals(this.sharpType))
            {
                return (this.sharpType + "," + this.quduanAd);
            }
            return (this.sharpType + ",-1");
        }

        public abstract string toStringKgl();
        public abstract string toStringXiangshu();
        public static void tryAddArray4checkLine(int[][][] array4checkLine, int i, int j, int k)
        {
            if ((((i >= 0) && (j >= 0)) && (i < array4checkLine.Length)) && (j < array4checkLine[i].Length))
            {
                try
                {
                    array4checkLine[i][j][k]++;
                }
                catch (Exception exception)
                {
                    Log.appendLog(exception.ToString(), "");
                }
            }
        }

        public virtual void xuanzhuan180(Point center2)
        {
            Point point = this.point;
            Size sizeDefine = this.sizeDefine;
            Point point2 = new Point(center2.X - point.X, center2.Y - point.Y);
            this.point = point2;
        }

        public int direction
        {
            get
            {
                return (int)this._direction.value;
            }
            set
            {
                this.mapData.ReDoStack.Push(this._direction, value);
                this._direction.value = value;
            }
        }

        public bool isHideTxt
        {
            get
            {
                return (bool)this._isHideTxt.value;
            }
            set
            {
                this.mapData.ReDoStack.Push(this._isHideTxt, value);
                this._isHideTxt.value = value;
            }
        }

        public bool isSel
        {
            get
            {
                return (bool)this._isSel.value;
            }
            set
            {
                this._isSel.value = value;
            }
        }

        public Color lineColor
        {
            get
            {
                return (Color)this._lineColor.value;
            }
            set
            {
                this.mapData.ReDoStack.Push(this._lineColor, value);
                this._lineColor.value = value;
            }
        }

        public Point point
        {
            get
            {
                return new Point((int)this._pointX.value, (int)this._pointY.value);
            }
            set
            {
                this.mapData.ReDoStack.Push(this._pointX, value.X);
                this._pointX.value = value.X;
                this.mapData.ReDoStack.Push(this._pointY, value.Y);
                this._pointY.value = value.Y;
            }
        }

        public int pointX
        {
            get
            {
                return (int)this._pointX.value;
            }
            set
            {
                this.mapData.ReDoStack.Push(this._pointX, value);
                this._pointX.value = value;
            }
        }

        public int pointY
        {
            get
            {
                return (int)this._pointY.value;
            }
            set
            {
                this.mapData.ReDoStack.Push(this._pointY, value);
                this._pointY.value = value;
            }
        }

        public Size sizeDefine
        {
            get
            {
                return new Size((int)this._sizeDefineWidth.value, (int)this._sizeDefineHeight.value);
            }
            set
            {
                this.mapData.ReDoStack.Push(this._sizeDefineHeight, value.Height);
                this._sizeDefineHeight.value = value.Height;
                this.mapData.ReDoStack.Push(this._sizeDefineWidth, value.Width);
                this._sizeDefineWidth.value = value.Width;
            }
        }

        public int sizeDefineHeight
        {
            get
            {
                return (int)this._sizeDefineHeight.value;
            }
            set
            {
                this.mapData.ReDoStack.Push(this._sizeDefineHeight, value);
                this._sizeDefineHeight.value = value;
            }
        }

        public int sizeDefineWidth
        {
            get
            {
                return (int)this._sizeDefineWidth.value;
            }
            set
            {
                this.mapData.ReDoStack.Push(this._sizeDefineWidth, value);
                this._sizeDefineWidth.value = value;
            }
        }

        public string subType
        {
            get
            {
                return (string)this._subType.value;
            }
            set
            {
                this.mapData.ReDoStack.Push(this._subType, value);
                this._subType.value = value;
            }
        }

        public string text
        {
            get
            {
                return (string)this._text.value;
            }
            set
            {
                this.mapData.ReDoStack.Push(this._text, value);
                this._text.value = value;
            }
        }

        public Color txtColor
        {
            get
            {
                return (Color)this._txtColor.value;
            }
            set
            {
                this.mapData.ReDoStack.Push(this._txtColor, value);
                this._txtColor.value = value;
            }
        }

        public string txtFont
        {
            get
            {
                return (string)this._txtFont.value;
            }
            set
            {
                this.mapData.ReDoStack.Push(this._txtFont, value);
                this._txtFont.value = value;
            }
        }

        public int txtSize
        {
            get
            {
                return (int)this._txtSize.value;
            }
            set
            {
                this.mapData.ReDoStack.Push(this._txtSize, value);
                this._txtSize.value = value;
            }
        }
    }
    /****************************************************/
    public class SharpOffset
    {
        public Point offset;
        public Sharp sharp;

        public SharpOffset(Sharp sharp, Point offset)
        {
            this.sharp = sharp;
            this.offset = offset;
        }
    }
}

